package com.qiongqi.datadir.utils;

import com.github.houbb.pinyin.constant.enums.PinyinStyleEnum;
import com.github.houbb.pinyin.util.PinyinHelper;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.collections4.IterableUtils.get;

public final class DnToStableVaultPath {

    // 路径前缀（按需修改）
    private static final String VAULT_BASE_PATH = "accon";

    /**
     * 转换DN为唯一且可重复的Vault路径
     * @param dn 原始DN（如 "CN=北京总公司, OU=技术部, O=阿里巴巴, C=CN"）
     * @return 标准化路径（如 "vault/pki/ca/cn/a_li_ba/ji_shu_bu/bei_jing_zong_gong_si_8e3d"）
     */
    public static String convertToVaultPath(String dn) {
        // 1. 解析DN为键值对（忽略大小写）
        Map<String, String> dnMap = parseDn(dn);

        // 2. 中文转拼音并规范化（核心步骤）
        dnMap.replaceAll((k, v) -> normalizeComponent(convertChineseToPinyin(v)));

        // 3. 构建层级路径（固定顺序）
        StringBuilder path = new StringBuilder(VAULT_BASE_PATH);
        appendComponent(path, dnMap.getOrDefault("C", "global"));
        appendComponent(path, dnMap.getOrDefault("O", "org"));
        appendComponent(path, dnMap.getOrDefault("OU", "unit"));
        appendComponent(path, dnMap.getOrDefault("CN", "node"));

        // 4. 附加DN的SHA-256前4位（唯一性保障，无随机性）
        path.append("_").append(sha256Suffix(dn));
        return path.toString();
    }

    /**
     * 中文转拼音，下划线分隔
     */
    private static String convertChineseToPinyin(String chinese) {
        String pinyinValue = chinese.matches(".*[\\u4e00-\\u9fa5]+.*")
                ? toInitials(chinese)
                : chinese;
        //return PinyinUtil.getPinyin(chinese, "_"); // 确保多字拼音用_连接
        return pinyinValue;
    }

    /**
     * 中文转拼音，多字拼音用_连接
     * @param chinese
     * @return
     */
    public static String toInitials(String chinese) {
        StringBuilder initials = new StringBuilder();
        for (int i = 0, j = length(chinese); i < j; i++) {
            char c = chinese.charAt(i);
            List<String> pinyinArray = PinyinHelper.toPinyinList(c);
            if (isNotEmpty(pinyinArray)) {
                // 取拼音首字母（如"zhong"取"z"）
                String firstChar = get(pinyinArray, 0);
                if (initials.length() > 0) {
                    initials.append('_');  // 非首字符前添加下划线
                }
                initials.append(firstChar);
            } else {
                // 非中文字符直接追加（如数字、英文）
                initials.append(c);
            }
        }
        return initials.toString();
    }

    /**
     * 解析DN到Map（统一转为大写键名）
     */
    private static Map<String, String> parseDn(String dn) {
        Map<String, String> map = new LinkedHashMap<>();
        for (String part : dn.split(",")) {
            String[] kv = part.trim().split("=", 2);
            if (kv.length == 2) {
                String key = upperCase(trim(kv[0])); // 键名统一大写
                map.put(key, trim(kv[1]));
            }
        }
        return map;
    }

    /**
     * 路径组件规范化（关键安全处理）
     */
    private static String normalizeComponent(String component) {
        return component
                .replaceAll("[^a-zA-Z0-9_]", "_")  // 非法字符转下划线
                .replaceAll("_{2,}", "_")          // 合并连续下划线
                .toLowerCase();                     // 统一小写
    }

    /**
     * 添加路径组件
     */
    private static void appendComponent(StringBuilder path, String component) {
        path.append("/").append(component);
    }

    /**
     * 生成固定长度的哈希后缀（SHA-256前4字符，确保确定性）
     */
    private static String sha256Suffix(String input) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash).substring(0, 4); // 取前4位十六进制字符
        } catch (Exception e) {
            throw new RuntimeException("SHA-256 calculation failed", e);
        }
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder hex = new StringBuilder();
        for (byte b : bytes) {
            hex.append(String.format("%02x", b));
        }
        return hex.toString();
    }

    public static String toPinyin(String chinese) {
        // 使用NORMAL模式（无音调小写）并移除空格
        return PinyinHelper.toPinyin(chinese, PinyinStyleEnum.NORMAL).replace(" ", "");
    }

//    public static String toInitials(String chinese) {
//        // 使用首字母模式并拼接
//        return PinyinHelper.toPinyin(chinese, PinyinStyleEnum.FIRST_LETTER).replace(" ", "");
//    }
}
